package com.sky.aspect;

import com.sky.annotition.AutoFill;
import com.sky.context.BaseContext;
import com.sky.enumeration.OperationType;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.time.LocalDateTime;

@Aspect
@Component
@Slf4j
public class AutoFillAspect {
    /**
     * 切入点
     */
    @Pointcut("execution(* com.sky.mapper.*.*(..)) && @annotation(com.sky.annotition.AutoFill)")
    public void autoFillPointcut() {}
    @Before("autoFillPointcut()")
    public void autoFill(JoinPoint joinPoint) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        log.info("开始进行公共字段自动填充...");

        //获取数据库mapper操作的类型是更新还是插入
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        AutoFill autoFill = signature.getMethod().getAnnotation(AutoFill.class);
        OperationType operationType = autoFill.value();

        Object[] args = joinPoint.getArgs();
        LocalDateTime now = LocalDateTime.now();
        Long currentId = BaseContext.getCurrentId();
        if (args.length == 0 || args[0] == null){
        }else{
            Object entity  = args[0];
            log.info("公共字段自动填充,操作类型:{}",operationType);
           if (operationType == OperationType.INSERT){
               Method setCreateTime = entity.getClass().getDeclaredMethod("setCreateTime", LocalDateTime.class);
               Method setUpdateTime = entity.getClass().getDeclaredMethod("setUpdateTime", LocalDateTime.class);
               Method setCreateUser = entity.getClass().getDeclaredMethod("setCreateUser", Long.class);
               Method setUpdateUser = entity.getClass().getDeclaredMethod("setUpdateUser", Long.class);
               setCreateTime.invoke(entity,now);
               setUpdateTime.invoke(entity

                       ,now);
               setCreateUser.invoke(entity,currentId);
               setUpdateUser.invoke(entity,currentId);
           }else {
               Method setUpdateTime = entity.getClass().getDeclaredMethod("setUpdateTime", LocalDateTime.class);
               Method setUpdateUser = entity.getClass().getDeclaredMethod("setUpdateUser", Long.class);
               setUpdateTime.invoke(entity,now);
               setUpdateUser.invoke(entity,currentId);
           }
        }
    }
}
